<template>
  <div class="appTemplate">
    <Header :title="'起步案例-加载3D模型'" :back="true"/>
    <main ref="threeView" class="main"></main>
    <Footer />
  </div>
</template>

<script setup lang="ts">
import Header from '@/components/Header.vue';
import Footer from '@/components/Footer.vue';
import {onMounted, ref} from "vue";
// 导入整个 three.js核心库
import * as THREE from 'three';
import { GLTFLoader } from "&t/examples/jsm/loaders/GLTFLoader";
import type { GLTF } from "&t/examples/jsm/loaders/GLTFLoader";
// 导入判断WebGL工具
import WebGL from "@/utils/WebGL";


THREE.Cache.enabled = true;
// 定义three场景显示区域
const threeView = ref();

// 创建场景
const scene = new THREE.Scene();
scene.background = new THREE.Color( 0x5a1216 );
// 雾
scene.fog = new THREE.Fog( 0xbe1480, 250, 1400 );
// 创建相机镜头
// 视野角度（fov）长宽比（aspect）近截面（near）远截面（far）
const camera = new THREE.PerspectiveCamera(110, window.innerWidth / window.innerHeight, 0.1, 1900);
camera.position.set( 0, 0, 1000 );
// 创建渲染器
const renderer = new THREE.WebGLRenderer();

onMounted(() => {
  if (WebGL.isWebGLAvailable()) {
    loadModel();
  } else {
    const warning = WebGL.getWebGLErrorMessage();
    threeView.value.appendChild(warning);
  }
})

// 加载字体
const loadModel = () => {
  const loader = new GLTFLoader();
  loader.load(`/src/assets/models/gltf/Parrot.glb`, (gltf: GLTF) => {
    const boomBox = gltf.scene;
    boomBox.position.set( 0, 0.2, 0 );
    boomBox.scale.set( 20, 20, 20 );
    scene.add( boomBox );
    renderer.setSize(threeView.value.offsetWidth - 15, threeView.value.offsetHeight - 15, true);
    threeView.value.appendChild(renderer.domElement);
    threeView.value.style.touchAction = "none";
    threeView.value.addEventListener( 'pointerdown', onPointerDown );
    renderer.render( scene, camera );
  })
}

const onPointerDown = (event: any) => {
  if ( event.isPrimary === false ) return;

  document.addEventListener( 'pointermove', onPointerMove );
  document.addEventListener( 'pointerup', onPointerUp );
}


const onPointerMove = ( event: any ) => {

  if ( event.isPrimary === false ) return;

  const pointerX = event.clientX - (window.innerWidth / 2);
  const pointerY = event.clientY - (window.innerHeight / 2);

  const targetRotationX = pointerX   * 0.02;
  const targetRotationY = pointerY   * 0.02;
  scene.rotation.y += (targetRotationX - scene.rotation.y) * 0.05;
  scene.rotation.x += (targetRotationY - scene.rotation.x) * 0.05;
  renderer.clear();
  renderer.render( scene, camera );
}

const onPointerUp = (event: any) => {

  if ( event.isPrimary === false ) return;

  document.removeEventListener( 'pointermove', onPointerMove );
  document.removeEventListener( 'pointerup', onPointerUp );

}

</script>

<style scoped>

</style>